package com.twb.auth.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.twb.auth.entity.twbOrganization.TwbOrganization;
import com.twb.auth.entity.twbRole.TwbRole;
import com.twb.auth.entity.twbRole.TwbRoleDataScope;
import com.twb.auth.entity.twbRole.TwbRoleResource;
import com.twb.auth.entity.twbRole.TwbRoleResourceAccredit;
import com.twb.auth.entity.twbRole.dto.GetTwbRoleByIdDto;
import com.twb.auth.entity.twbRole.dto.SearchTwbRoleDto;
import com.twb.auth.entity.twbRole.vo.SaveTwbRoleVo;
import com.twb.auth.entity.twbRole.vo.SearchTwbRoleVo;
import com.twb.auth.entity.twbTenantInfo.TwbTenantInfo;
import com.twb.auth.entity.twbUser.TwbUserRole;
import com.twb.auth.mapper.TwbRoleMapper;
import com.twb.auth.mapper.TwbUserMapper;
import com.twb.auth.service.ITwbOrganizationService;
import com.twb.auth.service.ITwbResourceService;
import com.twb.auth.service.ITwbRoleService;
import com.twb.auth.service.ITwbTenantInfoService;
import com.twb.core.base.entity.BaseLoginUser;
import com.twb.core.base.service.impl.BaseService;
import com.twb.core.constants.TwbConstants;
import com.twb.core.exception.ServiceException;
import com.twb.core.util.BeanUtils;
import com.twb.core.util.TwbPageUtil;

/**
 * @ClassName TwbRoleService
 * @Description 角色service
 * @author DSY
 * @date 2018年11月6日 下午4:25:07
 */
@Service("twbRoleService")
public class TwbRoleService extends BaseService<TwbRoleMapper,TwbRole> implements ITwbRoleService {

	@Autowired
	TwbRoleMapper twbRoleMapper;

	@Autowired
	ITwbOrganizationService twbOrganizationService;

	@Autowired
	ITwbResourceService twbResourceService;

	@Autowired
	TwbUserMapper twbUserMapper;
	
	@Autowired
	ITwbTenantInfoService twbTenantInfoService;
	
	@Override
	public Set<TwbRole> listRoleByUserId(String userId) {
		// TODO Auto-generated method stub
		return twbRoleMapper.listRoleByUserId(userId);
	}

	@Override
	public GetTwbRoleByIdDto getTwbRoleById(String id) {

		return twbRoleMapper.getTwbRoleById(id);
	}

	@Override
	public List<SearchTwbRoleDto> searchTwbRole(SearchTwbRoleVo vo) {
		BaseLoginUser loginUser = getLoginUser();
		String parentId = vo.getOrgId();
		//如果parentId为空，则默认传递当前登录用户所属租户的组织机构ID
		if(StringUtils.isBlank(parentId)) {
			if (!loginUser.isDeveloper()) {
				String tenantId = loginUser.getTenantId();
				if (StringUtils.isNotBlank(tenantId)) {
					TwbTenantInfo tenantInfo = twbTenantInfoService.getById(tenantId);
					vo.setOrgId(tenantInfo.getOrgId());
				}
			}
		}
		if (StringUtils.isNotBlank(parentId) && vo.getIsAllChildNode()) {
			TwbOrganization twbOrganization = twbOrganizationService.getById(parentId);
			vo.setOrgSearchKey(twbOrganization.getSearchKey());
			vo.setOrgId(null);
		}

		TwbPageUtil.orderBy(vo.getSorts());
		List<SearchTwbRoleDto> list = twbRoleMapper.searchTwbRole(vo);
		return list;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean saveTwbRole(SaveTwbRoleVo vo) {
		if (null == vo.getRoleSeq() || vo.getRoleSeq() == 0) {
			Integer orgSeq = twbRoleMapper.getMaxSeqByOrgId(vo.getOrgId());
			if (null == orgSeq) {
				orgSeq = 1;
			} else {
				orgSeq = orgSeq + 1;
			}
			vo.setRoleSeq(orgSeq);
		}

		TwbRole record = new TwbRole();
		record.setId(vo.getId());
		BeanUtils.copyNotNullProperties(vo, record);
		this.setCreateInfo(record);
		TwbOrganization twbOrganization = twbOrganizationService.getById(vo.getOrgId());
		String tenantId = twbOrganization.getTenantId() == null ? TwbConstants.DEFAULT_TENANTID : twbOrganization.getTenantId();
		record.setTenantId(tenantId);
		return this.save(record);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deleteTwbRoleById(String id) {
		// 查询该角色下是否存在用户，如果存在，不允许删除
		int userCount = twbRoleMapper.getUserCountByRoleId(id);
		if (userCount > 0) {
			throw new ServiceException("5001", "该角色下存在用户信息，不允许删除");
		}
		// 删除该用户的资源信息
		twbRoleMapper.deleteResourceByRoleId(id);
		// 删除该角色的授权资源信息
		twbRoleMapper.deleteAccreditResourceByRoleId(id);
		//删除该角色的数据授权信息
		twbRoleMapper.deleteRoleDataScope(id);
		return this.removeById(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int saveRoleResource(String roleId, String resIds, String projectId) {
		TwbRole twbRole = this.getById(roleId);
		if (twbRole == null) {
			throw new ServiceException("角色" + roleId + "未找到");
		}
		int delResult = twbRoleMapper.deleteRoleResourceByRoleId(roleId, projectId);
		if(StringUtils.isBlank(resIds)) {
			return delResult;
		}
		String[] ids = resIds.split(",");
		List<TwbRoleResource> list = new ArrayList<TwbRoleResource>();
		for (String resId : ids) {
			/*TwbResource twbResource = twbResourceService.get(resId);
			if (twbResource == null) {
				throw new ServiceException("资源" + resId + "未找到");
			}*/

			TwbRoleResource roleResource = new TwbRoleResource();
			roleResource.setRoleId(roleId);
			roleResource.setResourceId(resId);
			list.add(roleResource);
//			result = result + twbRoleMapper.saveRoleResource(roleResource);
		}
		int result = 0;
		String dbType = twbConfigProperties.getDbType();
		if(dbType.equals(TwbConstants.DbType.ORACLE)) {
			result = twbRoleMapper.insertRoleResBatchForOracle(list);
		} else {
			result = twbRoleMapper.insertRoleResBatchForMysql(list);
		}
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int saveRoleAccreditResource(String roleId, String resIds, String projectId) {
		TwbRole twbRole = this.getById(roleId);
		if (twbRole == null) {
			throw new ServiceException("角色" + roleId + "未找到");
		}

		int delResult = twbRoleMapper.deleteRoleAccreditResourceByRoleId(roleId, projectId);
		if(StringUtils.isBlank(resIds)) {
			return delResult;
		}
		String[] ids = resIds.split(",");
		List<TwbRoleResourceAccredit> list = new ArrayList<TwbRoleResourceAccredit>();
		for (String resId : ids) {
			/*TwbResource twbResource = twbResourceService.get(resId);
			if (twbResource == null) {
				throw new ServiceException("资源" + resId + "未找到");
			}*/

			TwbRoleResourceAccredit roleResource = new TwbRoleResourceAccredit();
			roleResource.setRoleId(roleId);
			roleResource.setResourceId(resId);
			list.add(roleResource);
//			result = result + twbRoleMapper.saveRoleAccreditResource(roleResource);
		}
		int result = 0;
		String dbType = twbConfigProperties.getDbType();
		if(dbType.equals(TwbConstants.DbType.ORACLE)) {
			result = twbRoleMapper.insertRoleResAccreditBatchForOracle(list);
		} else {
			result = twbRoleMapper.insertRoleResAccreditBatchForMysql(list);
		}
		return result;
	}

	@Override
	public List<String> listRoleIdsByUserId(String userId) {
		// TODO Auto-generated method stub
		return twbRoleMapper.listRoleIdsByUserId(userId);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int saveRoleUsers(String roleId, String userIds) {
		int result = 0;

		TwbRole twbRole = getById(roleId);

		if (twbRole == null) {
			throw new ServiceException("角色" + twbRole + "未找到");
		}

		for (String uid : userIds.split(",")) {
			Integer searchRoleUserCount = twbRoleMapper.searchRoleUserCount(uid, roleId);

			if (searchRoleUserCount == 0) {
				TwbUserRole userRole = new TwbUserRole();
				userRole.setUserId(uid);
				userRole.setRoleId(roleId);
				result = result + twbUserMapper.saveUserRole(userRole);
			}
		}

		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int deleteRoleUser(String roleId, String userIds) {
		int result = 0;

		for (String uid : userIds.split(",")) {
			result += twbRoleMapper.deleteRoleUser(uid, roleId);
		}

		return result;
	}

	@Override
	public int saveRoleDataScope(String roleId, List<String> orgIds) {
		if(!orgIds.isEmpty()) {
			twbRoleMapper.deleteRoleDataScope(roleId);
			
			List<TwbRoleDataScope> list = new ArrayList<>();
			for (String orgId : orgIds) {
				TwbRoleDataScope dataScope = new TwbRoleDataScope();
				dataScope.setRoleId(roleId);
				dataScope.setOrgId(orgId);
				list.add(dataScope);
			}
			String dbType = twbConfigProperties.getDbType();
			if(dbType.equals(TwbConstants.DbType.ORACLE)) {
				return twbRoleMapper.insertRoleDataScopeBatchForOracle(list);
			} else {
				return twbRoleMapper.insertRoleDataScopeBatchForMysql(list);
			}
		}
		return 0;
	}

	@Override
	public int deleteRoleDataScope(String id) {
		
		return twbRoleMapper.deleteRoleDataScope(id);
	}

	@Override
	public List<String> listRoleDataScopes(String id) {
		// TODO Auto-generated method stub
		return twbRoleMapper.listRoleDataScopes(id);
	}

}
